#ifndef GAME_H
#define GAME_H

#include <ncurses.h>
#include <string>
#include <vector>
#include <memory>
#include <utility>
#include <chrono>
#include <thread>
#include <atomic>
#include <mutex>
#include <condition_variable>

#include "snake.h"
#include <SDL2/SDL_mixer.h>
#include <SDL2/SDL.h>
#include "snake.h"

enum Mode{Normal,TimeLimited};
enum SpeedMode{Slow,Medium,Fast};
enum State{Lived,Invicible,Bash};

class Game
{
public:
    Game();
    ~Game();
    
    int renderMainMenu() const;
    void createInformationBoard();
    void renderInformationBoard() const;
    void createGameBoard();
    void renderGameBoard() const;
    void createInstructionBoard();
    void renderInstructionBoard() const;
    void loadLeadBoard();
    void updateLeadBoard();
    bool readLeaderBoard();
    bool updateLeaderBoard();
    bool writeLeaderBoard();
    void renderLeaderBoard() const;
    void renderBoards() const;
    void initializeGame();
    void runGame();
    void renderPoints() const;
    void renderDifficulty() const;
    void createRamdonFood();
    void renderFood() const;
    void renderSnake() const;
    void controlSnake() const;
    void startGame();
    bool renderRestartMenu() const;
    void adjustDelay();
    void initializeObstacles(); 
    void createRandomObstacle(); 
    bool isObstacleAt(int x, int y) const; 
    bool isObstacleCollision() const; 
    void renderObstacles() const; 
    void countDown();
    void updateTimeDisplay();
    void renderHelpBoard() const;
    void renderRankBoard() const;
    void initializeTimeadder(); 
    void createRandomTimeadder(); 
    bool touchTimeadder() const; 
    void renderTimeadder() const; 
    void renderLives() const;

    int renderSpeedMenu() const; 

    int renderPauseMenu() const; 

    bool isFoodEaten() const; 

private:
    int mScreenWidth;
    int mScreenHeight;
    int mGameBoardWidth;
    int mGameBoardHeight;
    const int mInformationHeight = 6;
    const int mInstructionWidth = 18;
    std::vector<WINDOW *> mWindows;
    const int mInitialSnakeLength = 2;
    const char mSnakeSymbol = '@';
    std::unique_ptr<Snake> mPtrSnake;
    SnakeBody mFood;
    const char mFoodSymbol = '#';
    int mPoints = 0;
    int mDifficulty = 0;
    int mBaseDelay = 100;
    int mDelay;
    const std::string mRecordBoardFilePath = "record";
    std::vector<int> mLeaderBoard_Normal;
    std::vector<int> mLeaderBoard_Timed;
    const int mNumLeaders = 3;
    std::vector<std::pair<int, int>> obstacles; 
    int maxObstacles; 
    const char obstacleSymbol = 'X';
    Mode mode;
    SpeedMode speedmode;
    std::atomic<bool> mRunning;
    std::atomic<int> mRemainingTime;
    std::thread mTimerThread;
    std::mutex mMutex;
    std::atomic<bool> mTimeUpdated{false};
    std::condition_variable mCv;
    bool mUpdatePending{false};
    WINDOW* mTimerWindow;
    int mLives = 3;
    const int mMaxLives = 3;
    std::chrono::time_point<std::chrono::steady_clock> mSlowStartTime;
    bool mIsSlowing = false;
    int mOriginalDelay;
    
    int mCurrentSpeed; // current speed level, 0 = slow, 1 = medium, 2 = fast.
    std::vector<std::vector<std::vector<int>>> mLeaderBoards; 
    Mix_Music* mBgMusic;
    Mix_Chunk* mEatSound;
    Mix_Chunk* mCollisionSound;
    Mix_Chunk* mGameOverSound;
    Mix_Chunk* mTurnSound;
    Mix_Chunk* mDashSound;
    bool mAudioInitialized;
    State state = State::Lived;

    //pause 
    bool mPaused; 

    //bash
    bool spacePressed = false; 
    int directionKey = 0; 
    bool mIsSpaceHeld = false; // 记录空格是否被持续按住
    
};

#endif